﻿using DotNetty.Transport.Channels;
using DotNetty.Transport.Libuv.Native;
using FileCommon.Models;
using FileEfCore.DbContexts;
using FileEfCore.FileInfo;
using FileServer.Core.Server.Processor;
using Microsoft.Extensions.DependencyInjection;

namespace FileServer.Core.Server.Handlers;

public class FileTransferServerHandler : ChannelHandlerAdapter
{
    private readonly IServerFileProcessor _serverFileProcessor;

    public FileTransferServerHandler(string rootPath)
    {
        _serverFileProcessor = new ServerFileProcessor(rootPath);
        _serverFileProcessor.OnTransferHandle += (sender, args) =>
        {
            using var dbContext = App.ServiceProvider.GetRequiredService<ServerFileDbContext>();
            var uploadFile = dbContext.FileStorageRecords.FirstOrDefault(p =>
                p.Actualfilename == args.FileName && p.FileStoragePath == args.ServerFileName);
            if (uploadFile == null)
            {
                var fileId = Guid.NewGuid();
                uploadFile = new FileStorageRecord()
                {
                    FileStorageRecordOID = fileId,
                    ID = fileId.ToString("N"),
                    Actualfilename = args.FileName,
                    FileStoragePath = args.ServerFileName,
                    Caption = args.FileName,
                    FileExtension = Path.GetExtension(args.ServerFileName),
                    FileSize = args.FileLength.ToString(),
                    SYS_Created = DateTime.Now,
                    ParentOID = Guid.Empty,
                    FileHash = args.MD5Hash,
                    SYS_LAST_UPD = DateTime.Now,

                };
                dbContext.Add(uploadFile);
                dbContext.SaveChanges();
            }
            // else if (uploadFile != null)
            // {
            //     if (args.OperationType == OperationType.Download && args.ProgressStatus == ProgressStatus.Start)
            //     {
            //         uploadFile.Version += 1;
            //     }
            //
            //     uploadFile.FileLength = args.FileLength;
            //     uploadFile.ProgressRate = args.ProgressRate;
            //     dbContext.Update(uploadFile);
            //     dbContext.SaveChanges();
            // }
        };
        // _serverFileProcessor.OnTransferCompleteHandle += (sender, args) =>
        // {
        //     using var dbContext = App.ServiceProvider.GetRequiredService<ServerFileDbContext>();
        //     var uploadFile = dbContext.FileStorageRecords.FirstOrDefault(p =>
        //         p.Actualfilename == args.FileName && p.FileStoragePath == args.ServerFileName);
        //     uploadFile.ProgressStatus = args.ProgressStatus;
        //     uploadFile.ProgressRate = args.ProgressRate;
        //     uploadFile.Remark = args.ErrorMessage;
        //     uploadFile.LastUpdateTime = DateTime.Now;
        //     dbContext.Update(uploadFile);
        //     dbContext.SaveChanges();
        // };
    }


    public override async void ChannelRead(IChannelHandlerContext context, object message)
    {
        if (message is UploadFileInfo uploadFileInfo)
        {
            try
            {
                switch (uploadFileInfo.OperationType)
                {
                    case OperationType.Upload:
                        await _serverFileProcessor.ServerWriteFile(context, uploadFileInfo);
                        break;
                    case OperationType.Download:
                        await _serverFileProcessor.ServerReadFile(context, uploadFileInfo);
                        break;
                    default:
                        throw new Exception("指定的操作类型错误");
                }
            }
            catch (Exception e)
            {
                uploadFileInfo.ErrorMessage = e.Message;
                uploadFileInfo.Success = false;
                if (context.Channel.Active && !(e is OperationException))
                {
                    await context.WriteAndFlushAsync(uploadFileInfo);
                }
            }
        }
    }
}